#include "mythread.hpp"
//#include "block_queue.hpp"
#include "circular_queue.hpp"
#include "task.hpp"
#include <string>
#include <unistd.h>
#include <ctime>
#include <vector>

using namespace my_thread;
//using block_queue_t = BlockQueue<Task>;
using circular_queue_t = CircularQueue<int>;

#define PRODUCTER_NUM 1
#define CONSUMER_NUM 3

class ThreadDate
{
public:
    ThreadDate(const std::string& thread_name, circular_queue_t& cq)
    : _thread_name(thread_name), _cq(cq)
    {}

    std::string _thread_name;
    circular_queue_t& _cq;
};

void product(ThreadDate &thread_data)
{
    //sleep(3);
    int data = 0;
    while (1)
    {
        std::cout << thread_data._thread_name <<" 生产数据：" << data << std::endl;
        thread_data._cq.push(data);
        data++;

        //sleep(1);
    }
    // sleep(3);
    // //int data = 0;
    // srand((unsigned int)time(nullptr));
    // while (1)
    // {
    //     int x = rand() % 100 + 1;
    //     int y = rand() % 100 + 1;
    //     Task task(x, y);

    //     std::cout << thread_data._thread_name << ": ";
    //     task.question();
    //     //std::cout << thread_data._thread_name <<" 生产数据：" << data << std::endl;
    //     thread_data._bq.push(task);
    //     //data++;

    //     sleep(1);
    // }
    
}
void consum(ThreadDate &thread_data)
{
    //sleep(5);
    int data;
    while (1)
    {
        sleep(2);
        thread_data._cq.pop(&data);
        std::cout << thread_data._thread_name <<" 消费数据：" << data << std::endl;
    }
    // //int data;
    // Task task(0, 0);
    // while (1)
    // {
    //     //sleep(1);
    //     thread_data._bq.pop(&task);
    //     std::cout << thread_data._thread_name << ": ";
    //     task.show_result();
    // }
}

void createThread(func_t<ThreadDate> func, std::vector<mythread<ThreadDate>> &threads, int threadNum, circular_queue_t &cq, const char *name)
{
    for (int i = 0; i < threadNum; i++)
    {
        char buf[64];
        sprintf(buf, "%s-%d", name, i + 1);

        ThreadDate* td = new ThreadDate(buf, cq);
        threads.emplace_back(func, *td, buf);
        threads.back().Start();
    }
}

void producterStart(std::vector<mythread<ThreadDate>> &threads, circular_queue_t &cq)
{
    createThread(product, threads, PRODUCTER_NUM, cq, "producter");
}

void consumerStart(std::vector<mythread<ThreadDate>> &threads, circular_queue_t &cq)
{
    createThread(consum, threads, CONSUMER_NUM, cq, "consumer");
}

void wait(std::vector<mythread<ThreadDate>> &threads)
{
    for (auto &thread : threads)
        thread.Join();
}

int main()
{
    std::vector<mythread<ThreadDate>> threads;
    threads.reserve(PRODUCTER_NUM + CONSUMER_NUM);  //预先开辟一段空间
    circular_queue_t cq(5);

    producterStart(threads, cq);
    consumerStart(threads, cq);

    wait(threads);
    return 0;
}

// #include <iostream>
// #include <unistd.h>
// #include <pthread.h>
// #include <vector>
// #include <cstdio>

// #define MASTER_NUM 1
// #define SLAVER_NUM 3

// pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
// pthread_cond_t g_cond = PTHREAD_COND_INITIALIZER;

// //master线程通过条件变量控制slaver线程
// void* master(void* arg)
// {
//     while (1)
//     {
//         sleep(2);
//         std::cout << "master 将唤醒一个线程………………" << std::endl;
//         pthread_cond_signal(&g_cond);
//     }

//     return nullptr;
// }
// void* slaver(void* arg)
// {
//     while (1)
//     {
//         pthread_mutex_lock(&g_mutex);
//         pthread_cond_wait(&g_cond, &g_mutex);
//         std::cout << "当前被唤醒的salver线程是：" <<(char*)arg << std::endl;
//         pthread_mutex_unlock(&g_mutex);
//     }

//     return nullptr;
// }

// void masterStart(std::vector<pthread_t>& tids)
// {
//     for (int i = 0; i < MASTER_NUM; i++)
//     {
//         char* buf = new char[64];
//         sprintf(buf, "Master-%d", i + 1);

//         pthread_t tid;
//         pthread_create(&tid, nullptr, master, buf);
//     }
// }

// void slaverStart(std::vector<pthread_t>& tids)
// {
//     for (int i = 0; i < SLAVER_NUM; i++)
//     {
//         char* buf = new char[64];
//         sprintf(buf, "Slaver-%d", i + 1);

//         pthread_t tid;
//         pthread_create(&tid, nullptr, slaver, buf);
//     }
// }

// void wait(std::vector<pthread_t>& tids)
// {
//     for (auto& tid: tids)
//     {
//         pthread_join(tid, nullptr);
//     }
// }

// int main()
// {
//     std::vector<pthread_t> tids;

//     masterStart(tids);
//     slaverStart(tids);

//     while(1);

//     wait(tids);

//     return 0;
// }